package com.tlgen.utils;

import com.google.common.collect.Lists;
import com.tlgen.annotation.ConfigFieldProperties;
import com.tlgen.model.AnnoClass;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;

import java.io.IOException;
import java.util.List;

public class ScanUtils {

    private static final String BASE_PACKAGE = "com.tlgen";
    private static final String RESOURCE_PATTERN = "/**/*.class";

    /**
     * 获取指定包下包含某个注解的所有类
     *
     * @return
     */
    public static List<AnnoClass> getDirectAnnotation() {
        List<AnnoClass> annoList = Lists.newArrayList();
        // spring 工具类, 可以获取指定路径下的全部类
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        try {
            String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    ClassUtils.convertClassNameToResourcePath(BASE_PACKAGE) + RESOURCE_PATTERN;
            Resource[] resources = resourcePatternResolver.getResources(pattern);
            // MetadataReader 的工厂类
            MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
            for (Resource resource : resources) {
                // 用于读取类信息
                MetadataReader reader = readerFactory.getMetadataReader(resource);
                // 扫描到的 class
                String className = reader.getClassMetadata().getClassName();
                Class<?> clazz = Class.forName(className);
                // 判断是否有指定主解
                ConfigFieldProperties anno = clazz.getAnnotation(ConfigFieldProperties.class);
                if (anno != null) {
                    // 将注解中的类型值作为 key, 对应的类作为 value
                    annoList.add(AnnoClass.builder().name(className).type(clazz).build());
                }
            }
        } catch (IOException | ClassNotFoundException e) {

        }
        return annoList;
    }

    /**
     * 获取 resource 的本地绝对路径
     * @return
     */
    public static String getResourceAbsolutePath() {
        String rootPath = "";
        ScanUtils scanUtils = new ScanUtils();
        String path = scanUtils.getClass().getResource("/").getPath();
        if (null != path) {
            rootPath = path.substring(1, path.indexOf("target"));
        }
        return rootPath;
    }

}
